<script setup lang="ts">
  import axios from 'axios'
  import { onMounted, Ref, ref } from 'vue'
  import { ElButton, ElDialog, ElButtonGroup, ElIcon } from 'element-plus'
  import { DocumentAdd, FolderAdd, Document, View, PictureFilled, Download } from '@element-plus/icons-vue'
  import 'element-plus/theme-chalk/index.css';
  // 样式
  import 'bpmn-js/dist/assets/diagram-js.css'
  import 'bpmn-js/dist/assets/bpmn-font/css/bpmn.css'
  import 'bpmn-js/dist/assets/bpmn-js.css'
  import 'bpmn-js/dist/assets/bpmn-font/css/bpmn-codes.css'
  import 'bpmn-js/dist/assets/bpmn-font/css/bpmn-embedded.css'
  import 'bpmn-js-properties-panel/dist/assets/element-templates.css';
  import 'bpmn-js-properties-panel/dist/assets/properties-panel.css';
  // bpmn构建器
  import BpmnModeler from 'bpmn-js/lib/Modeler.js' // 引入 bpmn-js
  // 初始化xml
  import diagramXML from '@/assets/bpmnXML'
  // 汉化
  import zh from '@/assets/zh'
  // 构建模块
  import {
    BpmnPropertiesPanelModule,
    BpmnPropertiesProviderModule,
    CamundaPlatformPropertiesProviderModule,
    CloudElementTemplatesPropertiesProviderModule
  } from 'bpmn-js-properties-panel'
  import camundaModdleDescriptor from 'camunda-bpmn-moddle/resources/camunda.json'

  const bpmn: Ref<HTMLDivElement | null> = ref(null)
  const bpmnPanel: Ref<HTMLDivElement | null> = ref(null)
  const fileElement: Ref<HTMLInputElement | null> = ref(null)
  const downloadLinkEl: Ref<HTMLLinkElement | null> = ref(null)
  const downloadSvgEl: Ref<HTMLLinkElement | null> = ref(null)
  let bpmnModeler: Ref<any> = ref(null)
  let perviewXMLShow = ref(false)
  let perviewSVGShow = ref(false)
  let perviewXMLStr = ref('')
  let perviewSVGData = ref('')

  onMounted(() => {
    bpmnModeler.value = new BpmnModeler({
      container: bpmn.value,
      propertiesPanel: {
        parent: bpmnPanel.value
      },
      additionalModules: [
        BpmnPropertiesPanelModule,
        BpmnPropertiesProviderModule,
        CamundaPlatformPropertiesProviderModule,
        {
          translate: [ 'value', customTranslate ]
        }
      ],
      moddleExtensions: {
        camunda: camundaModdleDescriptor
      }
    })
    createNewDiagram()

    let map = getParameterMap();
    const deploymentId = map?.get("deploymentId");
    const resourceName = map?.get("resourceName");
    if (deploymentId && resourceName) {
      var api=`../prod-api/processDefinition/getDefinitionXML?deploymentId=${deploymentId}&resourceName=${resourceName}`;
      //2.使用axios 进行get请求
      axios.get(api).then((res)=>{
        //请求成功的回调函数
        console.log(res)
        bpmnModeler.value.importXML(res.data.replace(/activiti.org\/bpmn/ig,"camunda.org/schema/1.0/bpmn").replace(/activiti/ig,"camunda"))
      }).catch((err)=>{
        //请求失败的回调函数
        console.log(err)
      })
    }
  })

  // 返回参数map
  function getParameterMap() {
    let parameters = window.location.search;
    // 如果没有参数
    if (parameters.indexOf("?") == -1) return null;
    let map = new Map;
    let strs = parameters.substr(1).split("&");
    for (let i = 0; i < strs.length; i++) {
      let str = strs[i].split("=");
      map.set(str[0], str[1]);
    }
    return map;
  }

  // 文件上传
  function fileChange() {
    if (fileElement.value && fileElement.value.files) {
      const file = fileElement.value.files[0]
      const fileReader = new FileReader();
      fileElement.value.value = ''
      fileReader.onload = (e: any) => {
        console.log(e.target.result);
        console.log('===================')
        bpmnModeler.value.importXML(e.target.result.replace(/activiti.org\/bpmn/ig,"camunda.org/schema/1.0/bpmn").replace(/activiti/ig,"camunda"))
        console.log(e.target.result.replace(/activiti.org\/bpmn/ig, "camunda.org/schema/1.0/bpmn").replace(/activiti/ig, "camunda"));
      }
      fileReader.readAsText(file);
    }
  }
  // 点击文件上传
  function upload() {
    fileElement.value?.click()
  }
  // 新建
  function newCreateDoc() {
    bpmnModeler.value.importXML(diagramXML)
  }
  // 下载XML
  async function downloadLinkClick() {
    try {
      const { xml } = await bpmnModeler.value.saveXML({ format: true });
      setEncoded(downloadLinkEl, 'diagram.bpmn', xml.replace(/camunda.org\/schema\/1.0\/bpmn/ig,"activiti.org/bpmn").replace(/camunda/ig,"activiti"));
    } catch (error) {
      console.error('下载失败');
    }
  }
  // 下载SVG
  async function downloadSvg() {
    try {
      const { svg } = await bpmnModeler.value.saveSVG();
      setEncoded(downloadSvgEl, 'diagram.svg', svg);
    } catch (error) {
      console.error('下载失败，请重试')
    }
  }
  // XML预览
  async function perviewXML() {
    try {
      const { xml } = await bpmnModeler.value.saveXML({ format: true });
      perviewXMLStr.value = xml.replace(/camunda.org\/schema\/1.0\/bpmn/ig,"activiti.org/bpmn").replace(/camunda/ig,"activiti");
      perviewXMLShow.value = true
    } catch (error) {
      console.error('预览失败，请重试')
    }
  }
  // SVG预览
  async function perviewSVG() {
    try {
      const { svg } = await bpmnModeler.value.saveSVG();
      perviewSVGData.value = svg
      perviewSVGShow.value = true
    } catch (error) {
      console.error('预览失败，请重试')
    }
  }
  // 汉化
  function customTranslate(template: any, replacements: any) {
    replacements = replacements || {};
    template = (zh as Record<string, string>)[template] || template;
    return template.replace(/{([^}]+)}/g, function(_: any, key: any) {
      return replacements[key] || '{' + key + '}';
    });
  }
  // 设置数据
  function setEncoded(link: Ref<HTMLLinkElement | null>, name: string, data: any) {
    const encodedData = encodeURIComponent(data);
    if (link.value && data) {
      link.value.className += ('active')
      link.value.setAttribute('href', 'data:application/bpmn20-xml;charset=UTF-8,' + encodedData)
      link.value.setAttribute('download', name)
    } else {
      link.value?.className.replace('active', '')
    }
  }
  // 创建BPMN区域
  function createNewDiagram() {
    openDiagram(diagramXML);
  }
  async function openDiagram(xml: string) {
    bpmnModeler.value.importXML(xml);
  }
</script>

<template>
  <div class="app-container">
    <div class="bpmn-main-box">
      <div ref="bpmn" id="bpmn-container" class="bpmn-container"></div>
      <div ref="bpmnPanel" id="js-properties-panel"></div>
    </div>
    <ul class="buttons">
      <input ref="fileElement" type="file" style="display: none" @change="fileChange"/>
      <el-button-group class="item download">
        <el-button type="primary" @click="upload()">
          <a title="上传文件"><el-icon><FolderAdd /></el-icon></a>
        </el-button>
        <el-button type="primary" @click="newCreateDoc()">
          <a title="新建"><el-icon><DocumentAdd /></el-icon></a>
        </el-button>
      </el-button-group>
      <el-button-group class="item download">
        <el-button @click="downloadLinkClick()" type="primary" >
          <a ref="downloadLinkEl" id="js-download-diagram" title="xml下载"><el-icon><Download /></el-icon></a>
        </el-button>
        <el-button @click="downloadSvg" type="primary" >
          <a ref="downloadSvgEl" id="js-download-svg" title="svg下载"><el-icon><PictureFilled /></el-icon></a>
        </el-button>
      </el-button-group>
      <el-button-group class="item download">
        <el-button type="primary" @click="perviewXML">
          <a title="xml预览"><el-icon><Document /></el-icon></a>
        </el-button>
        <el-button type="primary" @click="perviewSVG">
          <a title="svg预览"><el-icon><View /></el-icon></a>
        </el-button>
      </el-button-group>
    </ul>
    <el-dialog title="XML预览" width="80%" v-model="perviewXMLShow">
      <div style="max-height: 65vh;overflow: auto;">
        <highlightjs language='html' :code="perviewXMLStr" />
      </div>
    </el-dialog>
    <el-dialog title="SVG预览" width="80%" v-model="perviewSVGShow">
      <div style="text-align: center;" v-html="perviewSVGData" />
    </el-dialog>
  </div>
</template>

<style lang="scss" scoped>
.app-container {
  position: relative;
  height: 100vh;
  width: 100%;
}
.buttons{
  position: absolute;
  bottom: 30px;
  display: flex;
  left: 50px;
  padding: 0;
  margin: 0;
  list-style: none;
  .item {
    margin-right: 10px;
  }
  .download button {
    padding: 0;
    a {
      padding: 8px 15px;
    }
  }
}
 .bpmn-main-box {
  width:100%;
  height:100%;
  display: flex;
 }
 .bpmn-container {
    width: 100%;
    height: 100%;
    background: url('')
      repeat !important;
 }
 #js-properties-panel {
  border: 1px solid rgba(0,0,0,0.1);
  width: 250px;
 }

 .code-block {
  white-space: pre;
  max-height: 600px;
  overflow-y: auto;
  font-size: medium;
  color: #a9b7c6;
  background: #282b2e;
  padding: 16px;
}

a {
  text-decoration: none;
  color: #fff;
}
</style>
